热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

拓端tecdat|sas文本挖掘案例:如何使用SAS计算WordMover的距离

原文链接:http:tecdat.cn?p6181原文出处:拓端数据部落公众号WordMover的距离(WMD)是用于衡量

原文链接:http://tecdat.cn/?p=6181


原文出处:拓端数据部落公众号

Word Mover的距离(WMD)是用于衡量两个文档之间差异的距离度量,它在文本分析中的应用是由华盛顿大学的一个研究小组在2015年引入的。


Word Mover距离的定义

WMD是两个文档之间的距离,作为将所有单词从一个文档移动到另一个文档所需的最小(加权)累积成本。通过解决以下线性程序问题来计算距离。

T ij表示文档d中的单词i在文档d'中移动到单词j的多少;

C(1; j)的表示从文件d中的单词我到文件d '中的单词J‘行进’的费用; 这里的成本是word2vec嵌入空间中的两个词'欧几里德距离;

如果字我出现Ç我在文档d次,我们记

WMD是地球移动器距离度量(EMD)的一个特例,这是一个众所周知的运输问题。


如何用SAS计算地球移动的距离?

SAS / OR是解决运输问题的工具。图1显示了一个带有四个节点和节点之间距离的传输示例,我从这个Earth Mover的距离文档中复制了这些节点。目标是找出从{x1 ,x2}到{y1,y2}的最小流量。现在让我们看看如何使用SAS / OR解决这个运输问题。

节点的权重和节点之间的距离如下。

图-1运输问题

datax_set;input_node_ $ _sd_;datalines;
x10.74x20.26;datay_set;
input_node_ $ _sd_;
datalines;
​y10.23y20.51;
dataarcdata;input_tail_ $ _head_ $ _cost_;datalines;
x1 y1155.7x1 y2252.3x2 y1292.9x2 y2198.2;proc optmodel;
setxNODES;
​num w{xNODES};
​setyNODES;
num u{yNODES};set ARCS;
num arcCost{ARCS};
readdatax_setintoxNODES=[_node_]w=_sd_;
readdatay_setintoyNODES=[_node_]u=_sd_;
readdataarcdataintoARCS=[_tail_ _head_]arcCost=_cost_;
varflow{inARCS}>=0;
impvar sumY =sum{jinyNODES}u[j];
minobj =(sum{inARCS}arcCost[i,j]* flow[i,j])/sumY;
con con_y{jinyNODES}:sum{inARCS}flow[i,j]= u[j];
con con_x{iinxNODES}:sum{<(i),j>inARCS}flow[i,j]<&#61; w[i];solve with lp / algorithm&#61;ns scale&#61;none logfreq&#61;1;print flow;​quit;


 

SAS / OR的解决方案如表-1所示&#xff0c;EMD是目标值&#xff1a;203.26756757。

表-1 EMD用SAS / OR计算

我用SAS / OR表2得到的流量数据显示如下&#xff0c;与上述地球移动器距离文档中公布的图表相同。

表-2 SAS / OR的流量数据

图-2运输问题流程图


如何用SAS计算Word Mover的距离

本文从Word嵌入到文档距离&#xff0c;通过删除WMD的第二个约束来减少计算&#xff0c;提出了一个名为放松的Word Mover距离&#xff08;RWMD&#xff09;的新度量。由于我们需要读取文字嵌入数据&#xff0c;因此我将向您展示如何使用SAS Viya计算两个文档的RWMD。

/* start CAS server */cas casauto host&#61;"host.example.com"port&#61;5570;libnamesascas1 cas;/* load documents into CAS */datasascas1.documents;infiledatalines delimiter&#61;&#39;|&#39;missover;lengthtext varchar(300);inputtext$ did;datalines;Obama speaks to the mediainIllinois.|1The President greets the pressinChicago.|2;run;/* create stop list*/datasascas1.stopList;infiledatalines missover;lengthterm $20;inputterm$;datalines;thetoin;run;/* load word embedding model */proc cas;loadtable path&#61;&#39;datasources/glove_100d_tab_clean.txt&#39;caslib&#61;"CASTestTmp"importOptions&#61;{fileType&#61;"delimited",delimiter&#61;&#39;\t&#39;,getNames&#61;True,guessRows&#61;2.0,varChars&#61;True}casOut&#61;{name&#61;&#39;glove&#39;replace&#61;True};run;quit;%macrocalculateRWMD(textDS&#61;documents,documentID&#61;did,text&#61;text,language&#61;English,stopList&#61;stopList,word2VectDS&#61;glove,doc1_id&#61;1,doc2_id&#61;2);/* text parsing and aggregation */proc cas;textParse.tpParse/table&#61;{name&#61;"&textDS",where&#61;"&documentID&#61;&doc1_id or &documentID&#61;&doc2_id"}docId&#61;"&documentID",language&#61;"&language",stemming&#61;False,nounGroups&#61;False,tagging&#61;False,offset&#61;{name&#61;"outpos",replace&#61;1},text&#61;"&text";run; textparse.tpaccumulate/parent&#61;{name&#61;"outparent1",replace&#61;1}language&#61;"&language",offset&#61;&#39;outpos&#39;,stopList&#61;{name&#61;"&stoplist"},terms&#61;{name&#61;"outterms1",replace&#61;1},child&#61;{name&#61;"outchild1",replace&#61;1},reduce&#61;1,cellweight&#61;&#39;none&#39;,termWeight&#61;&#39;none&#39;;run;quit;/* terms of the two test documents */proc cas;loadactionset"fedsql";execdirect casout&#61;{name&#61;"doc_terms",replace&#61;true}query&#61;"select outparent1.*,_term_from outparent1left join outterms1on outparent1._termnum_ &#61; outterms1._termnum_where _Document_&#61;&doc1_id or _Document_&#61;&doc2_id;";run;quit;/* term vectors and counts of the two test documents */proc cas;loadactionset"fedsql";execdirect casout&#61;{name&#61;"doc1_termvects",replace&#61;true}query&#61;"select word2vect.*from &word2VectDS word2vect, doc_termswhere _Document_&#61;&doc2_id and lowcase(term) &#61; _term_;";run; execdirect casout&#61;{name&#61;"doc1_terms",replace&#61;true}query&#61;"select doc_terms.*from &word2VectDS, doc_termswhere _Document_&#61;&doc2_id and lowcase(term) &#61; _term_;";run; simple.groupBy /table&#61;{name&#61;"doc1_terms"}inputs&#61;{"_Term_","_Count_"}aggregator&#61;"n"casout&#61;{name&#61;"doc1_termcount",replace&#61;true};run;quit;proc cas;loadactionset"fedsql";execdirect casout&#61;{name&#61;"doc2_termvects",replace&#61;true}query&#61;"select word2vect.*from &word2VectDS word2vect, doc_termswhere _Document_&#61;&doc1_id and lowcase(term) &#61; _term_;";run; execdirect casout&#61;{name&#61;"doc2_terms",replace&#61;true}query&#61;"select doc_terms.*from &word2VectDS, doc_termswhere _Document_&#61;&doc1_id and lowcase(term) &#61; _term_;";run; simple.groupBy /table&#61;{name&#61;"doc2_terms"}inputs&#61;{"_Term_","_Count_"}aggregator&#61;"n"casout&#61;{name&#61;"doc2_termcount",replace&#61;true};run;quit;/* calculate Euclidean distance between words */datadoc1_termvects;setsascas1.doc1_termvects;run;datadoc2_termvects;setsascas1.doc2_termvects;run;proc iml;use doc1_termvects;read allvar_char_intolterm;read allvar_num_intox;closedoc1_termvects; use doc2_termvects;read allvar_char_intorterm;read allvar_num_intoy;closedoc2_termvects; d &#61; distance(x,y); lobs&#61;nrow(lterm);robs&#61;nrow(rterm);d_out&#61;j(lobs*robs, 3, &#39; &#39;);doi&#61;1to lobs;doj&#61;1to robs;d_out[(i-1)*robs&#43;j,1]&#61;lterm[i];d_out[(i-1)*robs&#43;j,2]&#61;rterm[j];d_out[(i-1)*robs&#43;j,3]&#61;cats(d[i,j]);end;end;createdistancefromd_out;appendfromd_out;closedistance;run;quit;/* calculate RWMD between documents */datax_set;setsascas1.doc1_termcount;rename_term_&#61;_node_;_weight_&#61;_count_;run;datay_set;setsascas1.doc2_termcount;rename_term_&#61;_node_;_weight_&#61;_count_;run;dataarcdata;setdistance;renamecol1&#61;_tail_;renamecol2&#61;_head_;length_cost_8;_cost_&#61; col3;run;proc optmodel;setxNODES;num w{xNODES};setyNODES;num u{yNODES};set ARCS;num arcCost{ARCS}; readdatax_setintoxNODES&#61;[_node_]w&#61;_weight_;readdatay_setintoyNODES&#61;[_node_]u&#61;_weight_;readdataarcdataintoARCS&#61;[_tail_ _head_]arcCost&#61;_cost_;varflow{inARCS}>&#61;0;impvar sumY &#61;sum{jinyNODES}u[j];minobj &#61;(sum{inARCS}arcCost[i,j]* flow[i,j])/sumY;con con_y{jinyNODES}:sum{inARCS}flow[i,j]&#61; u[j];/* con con_x {i in xNODES}: sum {<(i),j> in ARCS} flow[i,j] <&#61; w[i];*/solve with lp / algorithm&#61;ns scale&#61;none logfreq&#61;1;callsymput(&#39;obj&#39;, strip(put(obj,best.)));createdataflowDatafrom[i j]&#61;{inARCS: flow[i,j].sol >0}col("cost")&#61;arcCost[i,j]col("flowweight")&#61;flow[i,j].sol;run;quit;%putRWMD&#61;&obj;%mendcalculateRWMD; %calculateRWMD(textDS&#61;documents,documentID&#61;did,text&#61;text,language&#61;English,stopList&#61;stopList,word2VectDS&#61;glove,doc1_id&#61;1,doc2_id&#61;2);proc printdata&#61;flowdata;run;quit;

WMD方法不仅可以测量文档的相似性&#xff0c;还可以通过可视化流数据来解释为什么这两个文档是相似的。

 


推荐阅读
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 根据最新发布的《互联网人才趋势报告》,尽管大量IT从业者已转向Python开发,但随着人工智能和大数据领域的迅猛发展,仍存在巨大的人才缺口。本文将详细介绍如何使用Python编写一个简单的爬虫程序,并提供完整的代码示例。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 掌握远程执行Linux脚本和命令的技巧
    本文将详细介绍如何利用Python的Paramiko库实现远程执行Linux脚本和命令,帮助读者快速掌握这一实用技能。通过具体的示例和详尽的解释,让初学者也能轻松上手。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 本文由瀚高PG实验室撰写,详细介绍了如何在PostgreSQL中创建、管理和删除模式。文章涵盖了创建模式的基本命令、public模式的特性、权限设置以及通过角色对象简化操作的方法。 ... [详细]
  • 深入理解Java泛型:JDK 5的新特性
    本文详细介绍了Java泛型的概念及其在JDK 5中的应用,通过具体代码示例解释了泛型的引入、作用和优势。同时,探讨了泛型类、泛型方法和泛型接口的实现,并深入讲解了通配符的使用。 ... [详细]
  • 本文介绍如何通过更改软件源来提前体验Ubuntu 8.10,包括详细的配置步骤和相关注意事项。 ... [详细]
  • openGauss每日一练:第6天 - 模式的创建、修改与删除
    本篇笔记记录了openGauss数据库中关于模式(Schema)的创建、修改和删除操作。通过这些操作,用户可以更好地管理和控制数据库对象。实验环境为openGauss 2.0.0,并使用由墨天轮提供的线上环境。 ... [详细]
author-avatar
心悦随鑫_196
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有